# Makefile for minimal RISC-V OS

# Toolchain
CC = riscv64-unknown-elf-gcc
LD = riscv64-unknown-elf-ld
OBJCOPY = riscv64-unknown-elf-objcopy
OBJDUMP = riscv64-unknown-elf-objdump

# Compiler flags
CFLAGS = -Wall -Wextra -O2 -fno-omit-frame-pointer -ggdb
CFLAGS += -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax
CFLAGS += -I.

# Linker flags
LDFLAGS = -z max-page-size=4096

# Source files
KERNEL_SRC = kernel/entry.S kernel/main.c kernel/uart.c

# Object files
KERNEL_OBJ = $(KERNEL_SRC:.c=.o)
KERNEL_OBJ := $(KERNEL_OBJ:.S=.o)

# Target
KERNEL = kernel.bin

# Default target
all: $(KERNEL)

# Build kernel binary
$(KERNEL): $(KERNEL_OBJ) kernel/kernel.ld
	$(LD) $(LDFLAGS) -T kernel/kernel.ld -o $(KERNEL) $(KERNEL_OBJ)

# Compile C files
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# Compile assembly files
%.o: %.S
	$(CC) $(CFLAGS) -c $< -o $@

# Run with QEMU
run: $(KERNEL)
	qemu-system-riscv64 -machine virt -bios none -kernel $(KERNEL) -nographic

# Run with QEMU and monitor (easier to exit)
run-monitor: $(KERNEL)
	qemu-system-riscv64 -machine virt -bios none -kernel $(KERNEL) -nographic -monitor stdio

# Run with QEMU in background (can be stopped with Ctrl+C)
run-bg: $(KERNEL)
	qemu-system-riscv64 -machine virt -bios none -kernel $(KERNEL) -nographic &

# Stop all QEMU processes
stop:
	pkill -f qemu-system-riscv64

# Debug with QEMU
debug: $(KERNEL)
	qemu-system-riscv64 -machine virt -bios none -kernel $(KERNEL) -nographic -s -S

# Clean build files
clean:
	rm -f $(KERNEL_OBJ) $(KERNEL)

# Disassemble kernel
disasm: $(KERNEL)
	$(OBJDUMP -S $(KERNEL) > kernel.disasm

.PHONY: all run debug clean disasm
